package com.wxy.school.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxy.school.common.R;
import com.wxy.school.dto.OrdersDto;
import com.wxy.school.dto.OrdersOrDishDto;
import com.wxy.school.entity.*;
import com.wxy.school.service.*;
import com.wxy.school.utils.BaseContext;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 王祥宇
 * @projectName school
 * @packageName com.wxy.school.controller
 * @data 2023/3/8 16:20
 * @description: TODO
 * @version: 1.0
 */

@RestController
@RequestMapping("school/orders")
public class OrdersController {
    
    @Resource
    private OrdersService ordersService;

    @Resource
    private UserService userService;

    @Resource
    private AddressBookService addressBookService;

    @Resource
    private OrdersOrDishService ordersOrDishService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private ShopService shopService;

    @Resource
    private DishService dishService;
    
    /**
     * @description: 获取订单列表
     * @author: 王祥宇 
     * @param: pageNum
     * @param: pageSize
     * @param: qurey
     * @return: com.wxy.school.common.R<com.baomidou.mybatisplus.extension.plugins.pagination.Page>
     */
    @GetMapping("/getOrdersList")
    public R<Page> get(int pageNum, int pageSize, String qurey){
        //创建Orders分页查询构造器
        Page<Orders> ordersPage = new Page<>(pageNum, pageSize);
        //创建OrdersDto分页查询构造器
        Page<OrdersDto> ordersDtoPage = new Page<>();
        //创建查询条件
        LambdaQueryWrapper<Orders> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotEmpty(qurey), Orders::getOrderId, qurey);
        lambdaQueryWrapper.orderByDesc(Orders::getCreateTime);
        //执行查询
        ordersService.page(ordersPage, lambdaQueryWrapper);
        //将ordersPage中除records的数据拷贝给ordersDtoPage
        BeanUtils.copyProperties(ordersPage, ordersDtoPage, "records");
        //获取records中的数据
        List<Orders> records = ordersPage.getRecords();
        //使用stream流对records数据进行处理
        List<OrdersDto> ordersDtoList = records.stream().map((item) -> {
            OrdersDto ordersDto = new OrdersDto();
            //将item中的数据拷贝给ordersDto
            BeanUtils.copyProperties(item, ordersDto);
            //获取用户id
            Long userid = item.getUserId();
            //根据用户id查询用户数据并复制给ordersDto的user属性
            ordersDto.setUser(userService.getById(userid));
            //获取地址信息id
            Long addressid = item.getAddressId();
            //根据地址id查询地址数据
            AddressBook addressBook = addressBookService.getById(addressid);
            //将地址数据里面的收获手机号赋值给ordersDto中的phone属性
            ordersDto.setPhone(addressBook.getPhone());
            //将全部的地址进行拼接并赋值给ordersDto中的address属性
            ordersDto.setAddress(addressBook.getAddress());
            //返回处理好数据的ordersDto对象
            return ordersDto;
        }).collect(Collectors.toList());
        //将处理好的ordersDto对象赋值给ordersDtoPage分页查询的records属性
        ordersDtoPage.setRecords(ordersDtoList);
        //返回ordersDtoPage的分页对象数据
        return R.success(ordersDtoPage);
    }

    /**
     * @description: 更新订单状态
     * @author: 王祥宇
     * @param: orders
     * @return: com.wxy.school.common.R<java.lang.String>
     */
    @PutMapping("/updateOrders")
    public R<String> update(@RequestBody Orders orders){
        ordersService.updateById(orders);
        if (orders.getOrderStatus() == 3){
            LambdaQueryWrapper<OrdersOrDish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(OrdersOrDish::getOrdersId, orders.getId());
            // 根据订单id查询orders_or_dish表中该订单下的所有菜品信息
            List<OrdersOrDish> ordersOrDishList = ordersOrDishService.list(lambdaQueryWrapper);
            int sum = 0;
            // 循环遍历将该订单下的所有菜品的数量进行累加
            for (OrdersOrDish ordersOrDish : ordersOrDishList) {
                sum = sum + ordersOrDish.getCount();
                Dish dish = dishService.getById(ordersOrDish.getDishId());
                dish.setRate(dish.getRate() + ordersOrDish.getCount());
                BaseContext.setThreadLocal(dish.getUpdateUser());
                dishService.updateById(dish);
            }
            LambdaQueryWrapper<Shop> shopLambdaQueryWrapper = new LambdaQueryWrapper<>();
            shopLambdaQueryWrapper.eq(Shop::getId, orders.getShopId());
            // 根据订单表中的shopId查询该订单所属的店铺信息
            Shop shop = shopService.getOne(shopLambdaQueryWrapper);
            // 加累加的菜品数量与原有的该店铺的月销量相加并更新该店铺的月销量
            shop.setSales(sum + shop.getSales());
            shopService.updateById(shop);
        }
        return R.success("订单状态已更新");
    }

    /**
     * @description: 添加订单信息
     * @author: 王祥宇
     * @param: ordersDto
     * @return: com.wxy.school.common.R<com.wxy.school.entity.Orders>
     */
    @PostMapping("/addOrders")
    public R<Orders> add(@RequestBody OrdersDto ordersDto){
        // 拼接键名
        String categoryKey = "userId" + "_" + ordersDto.getUserId() + "-" + "shopId" + "_" + ordersDto.getShopId();
        String shoppingCartKey = "userId" + "_" + ordersDto.getUserId() + "-" + "shoppingCart" + "_" + ordersDto.getShopId();
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersDto, orders);
        // 根据当前时间戳生成订单编号
        orders.setOrderId(DateUtils.formatDate(new Date(), "yyyyMMdd") + System.currentTimeMillis());
        // 设置支付时间
        orders.setPayTime(LocalDateTime.now());
        // 设置订单创建时间
        orders.setCreateTime(LocalDateTime.now());
        // 保存订单信息
        ordersService.save(orders);
        // 使用stream流遍历该订单下的所有的菜品信息
        List<OrdersOrDish> ordersOrDishList = ordersDto.getShoppingCartDtoList().stream().map((item) -> {
            OrdersOrDish ordersOrDish = new OrdersOrDish();
            // 设置菜品绑定的订单id
            ordersOrDish.setOrdersId(orders.getId());
            // 设置菜品的id
            ordersOrDish.setDishId(item.getDishId());
            // 设置菜品的数量
            ordersOrDish.setCount(item.getNumber());
            // 设置菜品的口味信息
            ordersOrDish.setFlavore(item.getFlavore());
            return ordersOrDish;
        }).collect(Collectors.toList());
        // 保存该订单下的菜品信息
        ordersOrDishService.saveBatch(ordersOrDishList);
        // 删除Redis缓存中的分类信息以及购物车信息
        redisTemplate.delete(categoryKey);
        redisTemplate.delete(shoppingCartKey);
        return R.success(orders);
    }

    /**
     * @description: 根据用户id查询该用户的所有订单信息
     * @author: 王祥宇
     * @param: userId
     * @param: subject
     * @return: com.wxy.school.common.R<java.util.List<com.wxy.school.dto.OrdersDto>>
     */
    @GetMapping("/getAllOrders")
    public R<List<OrdersDto>> getAllOrders(Long userId, String subject){
        LambdaQueryWrapper<Orders> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Orders::getUserId, userId);
        // 根据订单名称进行模糊查询， 当subject不为空时添加该查询条件
        lambdaQueryWrapper.like(StringUtils.isNotEmpty(subject), Orders::getSubject, subject);
        // 根据用户id查询所有订单信息
        List<Orders> ordersList = ordersService.list(lambdaQueryWrapper);
        List<OrdersDto> ordersDtoList = ordersList.stream().map((item) -> {
            OrdersDto ordersDto = new OrdersDto();
            BeanUtils.copyProperties(item, ordersDto);
            Long shopId = item.getShopId();
            LambdaQueryWrapper<Shop> shopLambdaQueryWrapper = new LambdaQueryWrapper<>();
            shopLambdaQueryWrapper.eq(Shop::getId, shopId);
            // 根据订单表中的shopId查询店铺信息并赋值给ordersDto
            ordersDto.setShop(shopService.getOne(shopLambdaQueryWrapper));
            Long ordersId = item.getId();
            LambdaQueryWrapper<OrdersOrDish> ordersOrDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
            ordersOrDishLambdaQueryWrapper.eq(OrdersOrDish::getOrdersId, ordersId);
            // 根据订单id查询orders_or_dish表中该订单下的所有菜品id
            List<OrdersOrDish> ordersOrDishList = ordersOrDishService.list(ordersOrDishLambdaQueryWrapper);
            List<OrdersOrDishDto> ordersOrDishDtoList = ordersOrDishList.stream().map((it) -> {
                OrdersOrDishDto ordersOrDishDto = new OrdersOrDishDto();
                BeanUtils.copyProperties(it, ordersOrDishDto);
                Long dishId = it.getDishId();
                LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
                dishLambdaQueryWrapper.eq(Dish::getId, dishId);
                // 根据dianId查询所有的菜品信息并赋值给ordersOrDishDto
                ordersOrDishDto.setDish(dishService.getOne(dishLambdaQueryWrapper));
                return ordersOrDishDto;
            }).collect(Collectors.toList());
            ordersDto.setOrdersOrDishDtoList(ordersOrDishDtoList);
            return ordersDto;
        }).collect(Collectors.toList());
        return R.success(ordersDtoList);
    }
}
